/**
  ETFAna project, Anyang Normal University && IMP-CAS
  \class ETFTOFWall
  \brief TOF Wall class. Just a container for holding hits.
  \author SUN Yazhou, asia.rabbit@163.com
  \since 2021-10-29
  \date 2021-10-29 last modified
  \attention
  changelog
  <table>
  <tr>  <th>Date         <th>Author      <th>Description                   </tr>
  <tr>  <td>2021-10-29   <td>Asia Sun    <td>file created                  </tr>
  </table>

  \copyright Copyright (c) 2021-2024 Anyang Normal U. && IMP-CAS with LGPLv3 LICENSE
*/

#ifndef ETFTOFWall_h
#define ETFTOFWall_h

#include <map>
#include "ETFDetector.h"

using std::map;

class TClonesArray;
class ETFHPTDCCh;
class ETFPlaHit;
class ETFTrack;

class ETFTOFWall : public ETFDetector{
public:
  ETFTOFWall(){}
  /// \param ns: number of strips; \param width: (effective) strip width in mm
  ETFTOFWall(const char *name, int ns = 30, double width = 41.67, double length = 1200.);
  virtual ~ETFTOFWall();

  virtual void Initialize() override; ///< initialize the detector
  /// add the data channel to the detector
  virtual void Assign(const ETFRawChannel *ch, unsigned uid) override;
  /// \brief usually we let them all pass, but select them in the ETFPlaHit::Filter() method
  /// speical for plastic scintillators, to get rid of L-R leading edge misalginment
  // virtual bool TrigBoundCheck(ETFHPTDCCh *ch) override{ return true; }
  virtual void PostAssign() override; ///< finish the processing of all the assigned data
  /// assign drift time start and fired strip id to DC hits during tracking processes
  virtual bool AssignDriftTimeStart(ETFTrack *trk) const;
  virtual void ConstructGraph() override; ///< add strip to fGDumb
  virtual void Register() override; ///< register hits to the main output tree

  ETFPlaHit *GetStrip(int id) const; ///< get fired strip by serial id
  TClonesArray *GetHits(){ return fHits; }
  TClonesArray *hits(){ return fHits; }
  virtual short GetNFiredStrip() const{ return fNFiredStrip; }
  short multi() const{ return fNFiredStrip; }

  void SetSingleEnded(bool opt = true){ fSingleEnded = opt; }
  bool IsSingleEnded() const{ return fSingleEnded; }
  /// number of single-end-fired strips
  virtual short GetNFiredStripSingle() const{ return fNFiredStripSingle; }
  short multiSingle() const{ return fNFiredStripSingle; }
  void SetNStripStrayBound(double lb, double hb);

  virtual void Print() override; ///< print the detector info
  virtual void DrawHits() override; ///< draw the hits

  // ClassDefOverride(ETFTOFWall, 0);

protected:
  /// \param stripId: 0-30, along x increasing direction
  /// \param udvh: 0-1-2-3: uv, uh, dv, dh
  virtual void AddHit(const ETFRawChannel *ch, int stripId, int udvh);

  int NS; //! ///< number of strips
  double WIDTH, LENGTH; //! ///< width and length of a plastic scintillator strip in mm
  bool fSingleEnded; //! ///< whether all the plastic bars are single-end-coupled with PMT
  TClonesArray *fHits; //! ///< an array of plastic strips
  int *fStripIdMap; //! int[NS]: stripId => id in fHits, for fired strip retrieval by id
  double *fDelayStr; //! ///< <stripId, delay> delay constants for each specific strip
  /// distance limits of trk to TOFW strip center (unit: /stripWidth)
  double fNStripStrayLB, fNStripStrayHB; //! ///< [LB, HB]
  short fNFiredStrip, fNFiredStripSingle; ///< those with fired status == 4, and singly fired ones
};

#endif
